/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ventas.beans;

import entities.FacturaMultimarca;
import entities.LineaFacturaMultimarca;
import entities.Pedido;
import entities.ProductoTalla;
import facades.FacturaMultimarcaFacade;
import facades.LineaFacturaMultimarcaFacade;
import facades.LineaPedidoFacade;
import facades.ProductoTallaFacade;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import javax.enterprise.event.Event;
import javax.enterprise.event.Observes;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import qualifiers.EventoEntidadEditada;
import qualifiers.EventoEntidadElegida;

/**
 *
 * @author damfercer
 */
@Named(value = "editarFacturaMultimarcaBean")
@SessionScoped
public class EditarFacturaMultimarcaBean implements Serializable {
    @Inject
    private FacturaMultimarcaFacade facturaMultimarcaFacade;
    @Inject
    private ProductoTallaFacade productoTallaFacade;
    @Inject
    private LineaFacturaMultimarcaFacade lineaFacturaMultimarcaFacade;
    @Inject
    private LineaPedidoFacade lineaPedidoFacade;
    @Inject MultiplicadoresBean multiplicadoresBean;
    @Inject
    @EventoEntidadEditada
    Event<FacturaMultimarca> eventoFacturaMultimarcaEditada;
    @Inject
    @EventoEntidadEditada
    Event<Pedido> eventoPedidoMultimarcaEditado;
    private List<LineaFacturaMultimarca> lineasFactura;
    private FacturaMultimarca facturaMultimarca;
    private List<Integer> idsAEditar;
    private Map<Integer, LineaFacturaMultimarca> idsPTAdd;
    private Map<Integer, LineaFacturaMultimarca> costesLineas;
    private Map<Integer,Integer> unidadesPedido;
    private Map<Integer,Integer> unidadesEnviadas;
    private BigInteger codigoBarras;
    /**
     * Creates a new instance of NuevoAlbaranMultimarcaBean
     */
    public EditarFacturaMultimarcaBean() {
        lineasFactura=new ArrayList<LineaFacturaMultimarca>();
        idsAEditar=new ArrayList<Integer>();
        idsPTAdd=new HashMap<Integer, LineaFacturaMultimarca>();
        costesLineas=new HashMap<Integer, LineaFacturaMultimarca>();
        unidadesPedido=new HashMap<Integer,Integer>();
        unidadesEnviadas=new HashMap<Integer,Integer>();
    }
    
    public void reinitBean(){
        lineasFactura=new ArrayList<LineaFacturaMultimarca>();
        idsAEditar=new ArrayList<Integer>();
        idsPTAdd=new HashMap<Integer, LineaFacturaMultimarca>();
        costesLineas=new HashMap<Integer, LineaFacturaMultimarca>();
        unidadesPedido=new HashMap<Integer,Integer>();
        unidadesEnviadas=new HashMap<Integer,Integer>();
    }
    
    public void onFacturaElegida(@Observes @EventoEntidadElegida FacturaMultimarca facturaMultimarca){
        this.setFacturaMultimarca(facturaMultimarca);
        reinitBean();
    }
    
    public void editarTodosDescuentos(){
        for(LineaFacturaMultimarca lineaFactura: facturaMultimarca.getLineaFacturaMultimarcaList()){
            lineaFactura.setDescuento(this.facturaMultimarca.getDescuento());
            //this.editarDescuento(lineaFactura);
        }
    }

    /**
     * @return the facturaMultimarca
     */
    public FacturaMultimarca getFacturaMultimarca() {
        return facturaMultimarca;
    }

    /**
     * @param facturaMultimarca the facturaMultimarca to set
     */
    public void setFacturaMultimarca(FacturaMultimarca facturaMultimarca) {
        this.facturaMultimarca = facturaMultimarca;
    }
    
    public List<ProductoTalla> recuperarProductosTallaAdd(){
        return productoTallaFacade.getProductosTallasAddFactura(facturaMultimarca);
    }
    
    public LineaFacturaMultimarca recuperarLineaMultimarcaDeProductoTalla(ProductoTalla pt){
        if(!idsPTAdd.containsKey(pt.getIdProductoTalla())){
            LineaFacturaMultimarca linea=new LineaFacturaMultimarca();
            linea.setCantidad(0);
            linea.setProductoTalla(pt);
            linea.setPvp(pt.getProducto().getPvp());
            linea.setDescuento(this.facturaMultimarca.getDescuento());
            linea.setFactura(facturaMultimarca);
            linea.setCoste(BigDecimal.ZERO);
            idsPTAdd.put(pt.getIdProductoTalla(), linea);
        }
        return idsPTAdd.get(pt.getIdProductoTalla());
    }
    
    public void editarDescuento(LineaFacturaMultimarca lfm){
        costesLineas.remove(lfm.getIdLineaFacturaMultimarca());
        addId(lfm);
    }
    
    public LineaFacturaMultimarca recuperarCosteLinea(LineaFacturaMultimarca lfm){
        if(!costesLineas.containsKey(lfm.getIdLineaFacturaMultimarca())){
            BigDecimal descuento=BigDecimal.ONE.subtract(lfm.getDescuento().divide(new BigDecimal(100)));
            BigDecimal coste=lfm.getCoste().multiply(new BigDecimal(lfm.getCantidad())).multiply(descuento);
            LineaFacturaMultimarca lin=new LineaFacturaMultimarca();
            lin.setCoste(coste);
            costesLineas.put(lfm.getIdLineaFacturaMultimarca(), lin);
        }
        return costesLineas.get(lfm.getIdLineaFacturaMultimarca());
    }
    
    
    public void editarCantidadAdd(ProductoTalla pt){
        Integer cantidad=recuperarLineaMultimarcaDeProductoTalla(pt).getCantidad();
        Integer restan=this.recuperarCantidadPedidaDeProductoTalla(pt)-this.recuperarCantidadServidaDeProductoTalla(pt);
        if(cantidad>restan){
            FacesContext context = FacesContext.getCurrentInstance();
            HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
            Locale locale=context.getViewRoot().getLocale();
            ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
            String errorNoPedidoElegido=rb.getString("ErrorCantidadSuperada");
            FacesMessage msg =new FacesMessage(errorNoPedidoElegido,errorNoPedidoElegido);
            msg.setSeverity(FacesMessage.SEVERITY_ERROR);
            context.addMessage(null, msg);
            context.renderResponse();
        }
    }
    
    public void editarCantidad(LineaFacturaMultimarca lfm){
        Integer restan=this.recuperarCantidadPedidaDeProductoTalla(lfm.getProductoTalla())-this.recuperarCantidadServidaDeProductoTalla(lfm.getProductoTalla());
        if(lfm.getCantidad()<=restan){
            costesLineas.remove(lfm.getIdLineaFacturaMultimarca());
            addId(lfm);
        }
        else{
            FacesContext context = FacesContext.getCurrentInstance();
            HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
            Locale locale=context.getViewRoot().getLocale();
            ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
            String errorNoPedidoElegido=rb.getString("ErrorCantidadSuperada");
            FacesMessage msg =new FacesMessage(errorNoPedidoElegido,errorNoPedidoElegido);
            msg.setSeverity(FacesMessage.SEVERITY_ERROR);
            context.addMessage(null, msg);
            context.renderResponse();
        }
        
    }
    
    public void editarCoste(LineaFacturaMultimarca lfm){
        BigDecimal costeUnitarioAntiguo=lfm.getCoste();
        BigDecimal nuevoCoste=recuperarCosteLinea(lfm).getCoste();
        BigDecimal nuevoCosteUnitario=nuevoCoste.divide(new BigDecimal(lfm.getCantidad()),RoundingMode.HALF_UP);
        BigDecimal relacion=nuevoCosteUnitario.divide(costeUnitarioAntiguo,RoundingMode.HALF_UP);
        BigDecimal nuevoDescuento=BigDecimal.ONE.subtract(relacion).multiply(new BigDecimal(100));
        lfm.setDescuento(nuevoDescuento);
        addId(lfm);
    }
    
    public void addId(LineaFacturaMultimarca lfm){
        if(!this.idsAEditar.contains(lfm.getProductoTalla().getIdProductoTalla())){
            this.idsAEditar.add(lfm.getProductoTalla().getIdProductoTalla());
        }
    }
    
    public String editar(){
        this.facturaMultimarcaFacade.edit(facturaMultimarca);
        for (Iterator<LineaFacturaMultimarca> iter=facturaMultimarca.getLineaFacturaMultimarcaList().iterator();iter.hasNext();) {
            LineaFacturaMultimarca lineaFacturaMultimarca=iter.next();
            if(this.idsAEditar.contains(lineaFacturaMultimarca.getProductoTalla().getIdProductoTalla())){
                if(lineaFacturaMultimarca.getProductoTalla().getIdProductoTalla()==null){
                    if(lineaFacturaMultimarca.getCantidad()!=0){
                        lineaFacturaMultimarcaFacade.create(lineaFacturaMultimarca);
                    }
                }
                else{
                    if(lineaFacturaMultimarca.getCantidad()==0){
                        lineaFacturaMultimarcaFacade.remove(lineaFacturaMultimarca);
                        iter.remove();
                    }
                    else{
                        lineaFacturaMultimarcaFacade.edit(lineaFacturaMultimarca);
                    }
                }
            }
        }
        eventoFacturaMultimarcaEditada.fire(facturaMultimarca);
        Collections.replaceAll(facturaMultimarca.getPedido().getFacturaMultimarcaList(), facturaMultimarca, facturaMultimarca);
        eventoPedidoMultimarcaEditado.fire(facturaMultimarca.getPedido());
        return "/views/ventas/Pedidos?faces-redirect=true";
    }
    
    public Integer recuperarCantidadPedidaDeProductoTalla(ProductoTalla pt){
        Integer cantidad=0;
        if(pt!=null){
            if(!unidadesPedido.containsKey(pt.getIdProductoTalla())){
                unidadesPedido.put(pt.getIdProductoTalla(), lineaPedidoFacade.getCantidadProductoTallaPedido(pt, this.facturaMultimarca.getPedido()));
            }
            cantidad=unidadesPedido.get(pt.getIdProductoTalla());
        }
        return cantidad;
    }
    
    public Integer recuperarCantidadServidaDeProductoTalla(ProductoTalla pt){
        Integer cantidad=0;
        if(pt!=null){
            if(!unidadesEnviadas.containsKey(pt.getIdProductoTalla())){
                unidadesEnviadas.put(pt.getIdProductoTalla(), lineaFacturaMultimarcaFacade.getCantidadEnvidadaDeProductoTallaPedidoYNoFactura(pt, this.facturaMultimarca.getPedido(),this.facturaMultimarca));
            }
            cantidad=unidadesEnviadas.get(pt.getIdProductoTalla());
        }
        return cantidad;
    }
    
    public Boolean puedeGuardar(){
        Boolean res=true;
        for(LineaFacturaMultimarca lineaFacturaMultimarca : facturaMultimarca.getLineaFacturaMultimarcaList()){
            Integer restan=this.recuperarCantidadPedidaDeProductoTalla(lineaFacturaMultimarca.getProductoTalla())-this.recuperarCantidadServidaDeProductoTalla(lineaFacturaMultimarca.getProductoTalla());
            if(restan<lineaFacturaMultimarca.getCantidad()){
                res=false;
            }
        }
        return res;
    }
    
    public Boolean puedeAdd(){
        Boolean res=true;
        for(LineaFacturaMultimarca lineaFacturaMultimarca : idsPTAdd.values()){
            Integer restan=this.recuperarCantidadPedidaDeProductoTalla(lineaFacturaMultimarca.getProductoTalla())-this.recuperarCantidadServidaDeProductoTalla(lineaFacturaMultimarca.getProductoTalla());
            if(restan<lineaFacturaMultimarca.getCantidad()){
                res=false;
            }
        }
        return res;
    }
    
    public void addLineas(){
        for(LineaFacturaMultimarca linea: idsPTAdd.values()){
            if(linea.getCantidad()!=0){
                BigDecimal multiplicador=multiplicadoresBean.recuperarMultiplicadorDeProductoYPedido(linea.getProductoTalla().getProducto(), linea.getFactura().getPedido());
                BigDecimal coste=linea.getProductoTalla().getProducto().getPvp().divide(multiplicador, RoundingMode.HALF_UP);
                linea.setCoste(coste);
                lineaFacturaMultimarcaFacade.create(linea);
                this.facturaMultimarca.getLineaFacturaMultimarcaList().add(linea);
            }
        }
        this.idsPTAdd.clear();
    }

    
    public void procesarCodigoBarras(){
        ProductoTalla pt=productoTallaFacade.getProductoTallaDeCodigoDeBarras(codigoBarras);
        if(pt!=null){
            if(idsPTAdd.containsKey(pt.getIdProductoTalla())){
                Integer restan=this.recuperarCantidadPedidaDeProductoTalla(pt)-this.recuperarCantidadServidaDeProductoTalla(pt);
                LineaFacturaMultimarca linea=idsPTAdd.get(pt.getIdProductoTalla());
                if(linea.getCantidad()>=restan){
                    FacesContext context = FacesContext.getCurrentInstance();
                    HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
                    Locale locale=context.getViewRoot().getLocale();
                    ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
                    String errorNoPedidoElegido=rb.getString("ErrorCantidadSuperada");
                    FacesMessage msg =new FacesMessage(errorNoPedidoElegido,errorNoPedidoElegido);
                    msg.setSeverity(FacesMessage.SEVERITY_ERROR);
                    context.addMessage(null, msg);
                    context.renderResponse();   
                }
                else{
                    linea.setCantidad(linea.getCantidad()+1);
                }
            }
            else{
                FacesContext context = FacesContext.getCurrentInstance();
                HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
                Locale locale=context.getViewRoot().getLocale();
                ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
                String errorNoPedidoElegido=rb.getString("ProductoTallaNoEstaEnPedido");
                FacesMessage msg =new FacesMessage(errorNoPedidoElegido,errorNoPedidoElegido);
                msg.setSeverity(FacesMessage.SEVERITY_ERROR);
                context.addMessage(null, msg);
                context.renderResponse();
            }
        }
        else{
            FacesContext context = FacesContext.getCurrentInstance();
            HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
            Locale locale=context.getViewRoot().getLocale();
            ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
            String errorNoPedidoElegido=rb.getString("ErrorNoExisteProductoTallaDeCodigoDeBarras");
            FacesMessage msg =new FacesMessage(errorNoPedidoElegido,errorNoPedidoElegido);
            msg.setSeverity(FacesMessage.SEVERITY_ERROR);
            context.addMessage(null, msg);
            context.renderResponse();
        }
        this.codigoBarras=null;
    }
    
    
    /**
     * @return the costesLineas
     */
    public Map<Integer, LineaFacturaMultimarca> getCostesLineas() {
        return costesLineas;
    }

    /**
     * @param costesLineas the costesLineas to set
     */
    public void setCostesLineas(Map<Integer, LineaFacturaMultimarca> costesLineas) {
        this.costesLineas = costesLineas;
    }

    /**
     * @return the codigoBarras
     */
    public BigInteger getCodigoBarras() {
        return codigoBarras;
    }

    /**
     * @param codigoBarras the codigoBarras to set
     */
    public void setCodigoBarras(BigInteger codigoBarras) {
        this.codigoBarras = codigoBarras;
    }
}
